package com.wang.getEnum.scanner;

import com.wang.getEnum.domain.EnumConstant;
import com.wang.getEnum.domain.EnumInfo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AssignableTypeFilter;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 枚举扫描工具：扫描指定包下的所有枚举并提取信息
 */
@Component
public class EnumScanner {

    // 从配置文件中读取要扫描的包路径
    @Value("${enum.scan.package:com.example.enums}")
    private String scanPackage;

    /**
     * 扫描指定包下的所有枚举类
     */
    public List<EnumInfo> scanEnums() {
        List<EnumInfo> enumInfos = new ArrayList<>();

        // 初始化类路径扫描器 (不使用默认过滤器)
        ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
        // 添加自定义过滤器, 扫描所有类 (后续再过滤枚举类)
        scanner.addIncludeFilter(new AssignableTypeFilter(Object.class));

        // 扫描指定包下的所有类
        scanner.findCandidateComponents(scanPackage).forEach(beanDefinition -> {
            try {
                // 加载类对象
                Class<?> clazz = Class.forName(beanDefinition.getBeanClassName());
                // 过滤非枚举类
                if (clazz.isEnum()) {
                    enumInfos.add(buildEnumInfo(clazz));
                }
            } catch (Exception e) {
                // 日志记录
                System.err.println("扫描枚举失败：" + beanDefinition.getBeanClassName() + "，原因：" + e.getMessage());
            }
        });

        return enumInfos;
    }

    /**
     * 构建枚举类信息 (反射提取详情)
     */
    private EnumInfo buildEnumInfo(Class<?> enumClass) throws IllegalAccessException {
        EnumInfo enumInfo = new EnumInfo();
        enumInfo.setClassName(enumClass.getName());
        enumInfo.setSimpleName(enumClass.getSimpleName());

        // 提取枚举常量 (如SUCCESS, ERROR)
        List<EnumConstant> constants = new ArrayList<>();
        for (Object enumConstant : enumClass.getEnumConstants()) {
            Enum<?> enumObj = (Enum<?>) enumConstant;
            EnumConstant constant = new EnumConstant();
            constant.setName(enumObj.name());
            constant.setOrdinal(enumObj.ordinal());

            // 提取自定义字段 (过滤静态字段)
            constant.setFields(getEnumFields(enumClass, enumConstant));
            constants.add(constant);
        }
        enumInfo.setConstants(constants);

        return enumInfo;
    }

    /**
     * 提取枚举常量的自定义字段 (如code,desc)
     */
    private Map<String, Object> getEnumFields(Class<?> enumClass, Object enumConstant) throws IllegalAccessException {
        Map<String, Object> fields = new HashMap<>();
        // 遍历所有声明的字段（不包含父类）
        for (Field field : enumClass.getDeclaredFields()) {
            // 过滤静态字段（枚举常量定义为静态，自定义字段通常为非静态）
            if (!Modifier.isStatic(field.getModifiers())) {
                field.setAccessible(true); // 允许访问私有字段
                fields.put(field.getName(), field.get(enumConstant));
            }
        }
        return fields;
    }
}
